package com.lzjn.code.web.util;

import com.lzjn.code.common.util.FieldUtil;
import com.lzjn.code.web.entity.GenerateCodeConfig;
import com.lzjn.code.web.entity.TableFieldConfig;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

public class CodeGenerateUtil {

	private GenerateCodeConfig config;
	private Map<String,Object> data;

	public CodeGenerateUtil(GenerateCodeConfig generateCodeConfig) {

		this.config = generateCodeConfig;
		this.data = initData(generateCodeConfig);
	}

	protected Configuration getConfiguration(File folderFile) throws IOException {
	    Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
	    cfg.setDirectoryForTemplateLoading(folderFile);
	    cfg.setLocale(Locale.CHINA);
	    cfg.setDefaultEncoding("UTF-8");
	    return cfg;
	}

	public void invoke() throws Exception {

		String folderPath = "generator/template/" + this.config.getPageModel();

		File folderFile = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + folderPath);
		File[] templateFiles = folderFile.listFiles();

		if(templateFiles != null) {
			for(File templateFile : templateFiles){

				String filePath = getPath(templateFile.getName().replace(".ftl", ""));

				Template template = getConfiguration(folderFile).getTemplate(templateFile.getName());
				Writer out = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");
				template.process(data, out);
				out.close();
			}
		}

	}

	private Map<String, Object> initData(GenerateCodeConfig generateCodeConfig){
		Map<String,Object> data = new HashMap<String,Object>();

		data.put("moduleName", generateCodeConfig.getModuleName());
		data.put("sourceBasePackage", generateCodeConfig.getSourceBasePackage());
		data.put("sourceIncludeModule", generateCodeConfig.getSourceIncludeModule());
		data.put("sqlBasePackage", generateCodeConfig.getSqlBasePackage());
		data.put("pageBasePackage", generateCodeConfig.getPageBasePackage());

		data.put("tableName", generateCodeConfig.getTableConfig().getTableName());
		data.put("entityName", generateCodeConfig.getTableConfig().getEntityName());
		data.put("description", generateCodeConfig.getTableConfig().getDescription());

		data.put("tableConfig", generateCodeConfig.getTableConfig());

		data.put("createDate", new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));
		data.put("author", generateCodeConfig.getAuthor());

		List<TableFieldConfig> fields = generateCodeConfig.getTableConfig().getFieldConfigs();

		data.put("fields", fields);

		List<TableFieldConfig> searchFields = new ArrayList<TableFieldConfig>();
		List<TableFieldConfig> formFields = new ArrayList<TableFieldConfig>();
		List<TableFieldConfig> sortFields = new ArrayList<TableFieldConfig>();

		for(TableFieldConfig field : fields){

			if("Y".equals(field.getPrimaryKey())){
				data.put("pkPropertyName", field.getPropertyName());
				data.put("pkPropertyType", field.getPropertyType());
				data.put("pkFieldName", field.getFieldName());
			}
			if(!"N".equals(field.getListQuery())) {

				searchFields.add(field);
			}
			if("Y".equals(field.getFormShow())) {

				formFields.add(field);
			}
			if(!"N".equals(field.getListSort())) {
				sortFields.add(field);
			}
		}

		data.put("searchFields", searchFields);
		data.put("formFields", formFields);
		data.put("sortFields", sortFields);

		int searchColumnNum = generateCodeConfig.getTableConfig().getSearchColumnNum();
		int formColumnNum = generateCodeConfig.getTableConfig().getFormColumnNum();

		data.put("searchColumnNum", searchColumnNum);
		data.put("formColumnNum", formColumnNum);
		data.put("searchColumnWidth", 12 / searchColumnNum);
		data.put("formColumnWidth", 12 / formColumnNum);

		return data;
	}

	private String getPath(String templateFileName) {

		StringBuilder path = new StringBuilder(config.getTargetPath());

		path.append("/");

		if(templateFileName.contains("_") && templateFileName.contains("xxx")) {

			String[] names = templateFileName.split("_");

			String suffix = names[0];
			String name = names[names.length - 1];

			String fileName = name.replace("xxx", config.getTableConfig().getEntityName()) + "." + suffix;

			if("java".equals(suffix)) {

				for(int i = 1; i < names.length - 1; i++) {
					path.append("/").append(names[i]);
				}

				if("Y".equals(config.getSourceIncludeModule())) {
					path.append("/").append(config.getModuleName());
				}

			} else if("xml".equals(suffix)) {

				path.append(config.getSqlBasePackage())
						.append("/")
						.append(config.getModuleName());

				fileName = name.replace("xxx", FieldUtil.getInitialSmall(config.getTableConfig().getEntityName())) + "." + suffix;

			} else {

				path.append(config.getPageBasePackage())
						.append("/")
						.append(config.getModuleName());

				fileName = name.replace("xxx", FieldUtil.getInitialSmall(config.getTableConfig().getEntityName())) + "." + suffix;
			}

			File folder = new File(path.toString());

			if(!folder.exists()) {
				folder.mkdirs();
			}

			path.append("/").append(fileName);
		}

		return path.toString();
	}

//	private String getPath(String templateFileName) {
//
//		StringBuilder path = new StringBuilder(config.getTargetPath());
//
//		path.append("/");
//
//		if(templateFileName.contains("_") && templateFileName.contains("xxx")) {
//
//			String[] names = templateFileName.split("_");
//
//			String suffix = names[0];
//			String name = names[1];
//
//
//			String fileName = name.replace("xxx", config.getTableConfig().getEntityName()) + "." + suffix;
//
//			if("java".equals(suffix)) {
//
////				path.append(config.getEntityPackage());
//
//				path.append("/");
//
//				if(name.contains("Impl") || name.contains("impl")) {
//
//					path.append(name.replace("xxx", "").replace("Impl", "").replace("impl", "").toLowerCase())
//						.append("/").append("impl");
//
//				}  else if(name.contains("DTO") || name.contains("Dto") || name.contains("dto")) {
//
//					path.append("dto");
//
//				} else if(name.contains("VO") || name.contains("vo")) {
//
//					path.append("vo");
//
//				} else if(name.contains("Model") || name.contains("model")) {
//
//					path.append("model");
//
//				} else {
//
//					String folder = name.replace("xxx", "");
//
//					if(StringUtils.isEmpty(folder)){
//						folder = "entity";
//					}
//
//					path.append(folder.toLowerCase());
//				}
//
//				if("Y".equals(config.getSourceIncludeModule())) {
//					path.append("/").append(config.getModuleName());
//				}
//
//			} else if("xml".equals(suffix)) {
//
//				path.append(config.getSqlBasePackage())
//					.append("/")
//					.append(config.getModuleName());
//
//				fileName = name.replace("xxx", FieldUtil.getInitialSmall(config.getTableConfig().getEntityName())) + "." + suffix;
//
//			} else {
//
//				path.append(config.getPageBasePackage())
//					.append("/")
//					.append(config.getModuleName());
//			}
//
//			File folder = new File(path.toString());
//
//			if(!folder.exists()) {
//				folder.mkdirs();
//			}
//
//			if(fileName.contains("Model")) {
//				path.append("/").append(fileName.replace("Model", ""));
//			} else {
//				path.append("/").append(fileName);
//			}
//
//		}
//
//		return path.toString();
//	}
}
